package com.pentajock.docdb.dialogs;

import com.pentajock.docdb.AdminWindow;
import com.pentajock.docdb.database.DBController;
import com.pentajock.docdb.images.DBImages;
import com.pentajock.docdb.lang.Lang;
import com.pentajock.docdb.types.User;
import com.pentajock.docdb.utils.Utils;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.util.*;
import javax.swing.*; 

public class UserDialog extends JDialog {
	private static final String CANCEL_DIALOG_INPUT_KEY = "CANCEL_DIALOG";
	private static final String newUserTitle = "Create New User";
	private static final String editUserTitle = "Edit User: ";
	
	//private User userAccount;
	private User editUser;
	private User adminUser;
	private JButton okButton;
	private JButton cancelButton;
	
	private JTextField userNameTextField;
	private JTextField firstNameTextField;
	private JTextField lastNameTextField;
	private JComboBox departmentComboBox;
	private JCheckBox supervisorCheckBox;
	private JCheckBox adminCheckBox;
	private JButton passwordButton;
	
	//private String userName;
	private boolean success;
	private boolean newUser;
	private boolean dialogCanceled;
	
	/* For editing an existing account */
	public UserDialog(AdminWindow owner, User e, User u) {
		super(owner, editUserTitle + e.getUserName(), true);
		constructHelper(e, u, false);
	}
	
	/* For creating a new account */
	public UserDialog(AdminWindow owner, User u) {
		super(owner, newUserTitle, true);
		constructHelper(new User(), u, true);
	}
	
	private void constructHelper(User editUser, User adminUser, boolean newUser) {
		this.newUser = newUser;
		this.editUser = editUser;
		setUser(adminUser);
		success = false;
		Utils.setIconImage(this, DBImages.getUserIconImage(editUser));
		//setIconImage(DBImages.getUserIconImage(editUser)); // java 1.6 only
		initializeObjects();
		layoutFrame();
		addListeners();
		getRootPane().setDefaultButton(okButton);
		setResizable(false);
		pack();
		setLocationRelativeTo(null);
	}
	
	private void initializeObjects() {
		Object[] depts;
		try {
			java.util.List<String> deptList = DBController.getAllDepartments();
			deptList.remove("-1"); // Remove Lost & Found Department
			depts = deptList.toArray();
		}
		catch (Exception e) {
			depts = new Object[] {"Error"};
		}
		if (editUser.getDepartmentName().equals("")) 
			editUser.setDepartmentName(adminUser.getDepartmentName());
		
		userNameTextField = new JTextField(editUser.getUserName());
		firstNameTextField = new JTextField(editUser.getFirstName());
		lastNameTextField = new JTextField(editUser.getLastName());
		departmentComboBox = new JComboBox(depts);
		departmentComboBox.setSelectedItem(editUser.getDepartmentName());
		supervisorCheckBox = new JCheckBox("", editUser.isSupervisor());
		adminCheckBox = new JCheckBox("", editUser.isAdmin());
		passwordButton = new JButton("Change");
		passwordButton.setToolTipText(Lang.TOOL_TIP.get("PW_CHANGE"));
		
		okButton = new JButton("OK");
		okButton.setDefaultCapable(true);
		okButton.setMnemonic(KeyEvent.VK_O);
		
		cancelButton = new JButton("Cancel");
		cancelButton.setMnemonic(KeyEvent.VK_C);
		
		passwordButton.setEnabled(!(editUser.getUserName() == ""));
	}
	
	private void layoutFrame() {
		int hAlign = SwingConstants.RIGHT;
		JLabel userNameLabel = new JLabel("User Name:", hAlign);
		userNameLabel.setDisplayedMnemonic('u');
		userNameLabel.setLabelFor(userNameTextField);
		
		JLabel firstNameLabel = new JLabel("First Name:", hAlign);
		firstNameLabel.setDisplayedMnemonic('f');
		firstNameLabel.setLabelFor(firstNameTextField);
		
		JLabel lastNameLabel = new JLabel("Last Name:", hAlign);
		lastNameLabel.setDisplayedMnemonic('l');
		lastNameLabel.setLabelFor(firstNameTextField);
		
		JLabel departmentLabel = new JLabel("Department:", hAlign);
		departmentLabel.setDisplayedMnemonic('d');
		departmentLabel.setLabelFor(departmentComboBox);
		
		JLabel supervisorLabel = new JLabel("Supervisor:", DBImages.USER_SUPER_ICON.getIcon(), hAlign);
		supervisorLabel.setDisplayedMnemonic('s');
		supervisorLabel.setLabelFor(supervisorCheckBox);
		
		JLabel adminLabel = new JLabel("Admin:", DBImages.USER_ADMIN_ICON.getIcon(), hAlign);
		adminLabel.setDisplayedMnemonic('a');
		adminLabel.setLabelFor(adminCheckBox);
		
		JLabel passwordLabel = new JLabel("Password:", DBImages.KEY_ICON.getIcon(), hAlign);
		passwordLabel.setDisplayedMnemonic('P');
		adminLabel.setLabelFor(passwordButton);
		
		passwordButton.setBorder(BorderFactory.createEtchedBorder());
		
		JPanel userPanel = new JPanel(new GridLayout(7, 2, 4, 4));
		userPanel.add(userNameLabel);
		userPanel.add(userNameTextField);
		userPanel.add(firstNameLabel);
		userPanel.add(firstNameTextField);
		userPanel.add(lastNameLabel);
		userPanel.add(lastNameTextField);
		userPanel.add(departmentLabel);
		userPanel.add(departmentComboBox);
		userPanel.add(supervisorLabel);
		userPanel.add(supervisorCheckBox);
		userPanel.add(adminLabel);
		userPanel.add(adminCheckBox);
		userPanel.add(passwordLabel);
		userPanel.add(passwordButton);
		
		JPanel buttonPanel = new JPanel(new FlowLayout());
		buttonPanel.add(okButton);
		buttonPanel.add(cancelButton);
		
		Container contentPane = getContentPane();
		contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
		contentPane.add(userPanel);
		contentPane.add(Box.createVerticalStrut(3));
		contentPane.add(new JSeparator(SwingConstants.HORIZONTAL));
		contentPane.add(Box.createVerticalStrut(3));
		contentPane.add(buttonPanel);
	}
	
	private void addListeners() {
		addComponentListener(new ComponentAdapter() {
			public void componentShown(ComponentEvent e) {
				//
			}
		});
		
		okButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(checkFields()) {
					try {
						if (!newUser && DBController.updateUser(editUser)) {
							success = true;
							setVisible(false);
						}
						else if(newUser && DBController.addUser(editUser)) {
							success = true;
							setVisible(false);
						}
					}
					catch (SQLException sql) {
							Dialogs.showError(sql, editUser, "Error inserting values into database");
					}
				}
			}
		});
		
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setVisible(false);
			}
		});
		
		passwordButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				showPasswordDialog();
			}
		});
		
		/*
		 * Input/Action mapping.
		 */
		InputMap inputMap = new ComponentInputMap((JComponent)getContentPane());
		inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), CANCEL_DIALOG_INPUT_KEY);
		
		ActionMap actionMap = new ActionMap();
		actionMap.put(CANCEL_DIALOG_INPUT_KEY, new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				setVisible(false);
			}
		});
		
		((JComponent)getContentPane()).setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
		((JComponent)getContentPane()).setActionMap(actionMap);
		/**/
	}
	
	private boolean checkFields() {
		String badFields = "";
		
		String userName = userNameTextField.getText().toLowerCase().trim();
		String firstName = firstNameTextField.getText().trim();
		String lastName = lastNameTextField.getText().trim();
		String departmentName = departmentComboBox.getSelectedItem().toString();
		boolean isSupervisor = supervisorCheckBox.isSelected();
		boolean isAdmin = adminCheckBox.isSelected();
		
		if (userName.length() < 1) 
			badFields += "* Username cannot be blank\n";
		if (firstName.length() < 1)
			badFields += "* First Name cannot be blank\n";
		if (lastName.length() < 1)
			badFields += "* Last Name cannot be blank\n";
		
		if (!editUser.getUserName().equalsIgnoreCase(userName)) {
			String tempDept = DBController.getUserDepartment(userName);
			if (!(tempDept == null)) {
				if (tempDept.equalsIgnoreCase(departmentName)) 
					badFields += "* User " + userName + " already exists in department " + departmentName;
			}
		}
		
		if (badFields.equals("")) {
			editUser.setUserName(userName);
			editUser.setFirstName(firstName);
			editUser.setLastName(lastName);
			editUser.setDepartmentName(departmentName);
			editUser.setIsSupervisor(isSupervisor);
			editUser.setIsAdmin(isAdmin);
			return true;
		}
		Dialogs.showError(newUser, badFields);
		return false;
	}

	private void showPasswordDialog() {
		PasswordDialog p = new PasswordDialog(this, editUser, adminUser);
		p.setVisible(true);
	}
	
	private void showMessage(String message, String title) {
		JOptionPane.showMessageDialog(this, message, title, JOptionPane.INFORMATION_MESSAGE);
	}
	
	//private void showError(String message) {
	//	JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
	//	DBClient.printDebug(message);
	//}
	
	private void resetFields() {
		userNameTextField.setText("");
		firstNameTextField.setText("");
		lastNameTextField.setText("");
		departmentComboBox.setSelectedIndex(0);
		supervisorCheckBox.setSelected(false);
		adminCheckBox.setSelected(false);
	}
	
	public void setUser(User adminUser) {
		if (adminUser.isAdmin())
			this.adminUser = adminUser;
		else
			setVisible(false);
	}
	
	public boolean isSuccessful() {
		return success;
	}
	
	public void setVisible(boolean b) {
		super.setVisible(b);
		dispose();
	}
}
